#include "TransferDriver.h"
#include "Ipmb.h"
#include "i2c_module_interface.h"
#include "Debug.h"
#include "Led.h"

#include "Driver_uart.h"
#include "Driver_i2c.h"
#include "IicCmd.h"
#include "Mmc.h"


int Transfer_TxData(IicTransfer* pTransfer, uint8* pData, uint8 len)
{
	return 0;
}

void Transfer_Init(Transfer* pTransfer, Ipmb* pIpmb)
{
	memset(pTransfer, 0, sizeof(Transfer));
	
	pTransfer->TxData = (TransferFun)Transfer_TxData;
	pTransfer->m_pIpmb = pIpmb;

	Ipmb_AttachTransfer(pIpmb, pTransfer);
}

int IicTransfer_TxData(IicTransfer* pTransfer, uint8* pData, uint8 len)
{
    int ret = ERR_FAILED;

	uint8 channel = pTransfer->m_bChannel;
	
    unsigned char RxBufStatus;
    unsigned char TxBufStatus;
    unsigned char EventStatus;
	
	TRACE_LEVEL(TRACE_IICTRANSFER | TRACE_INTEG_TEST, ("%s(%d) Dump Data: ", _FUNC_, len));	
	DUMP_BYTE_LEVEL(TRACE_IICTRANSFER | TRACE_INTEG_TEST, pData, len);	
	
    if(I2C_GetStatus(channel, &RxBufStatus, &TxBufStatus, &EventStatus) == 0)
    {
		//PRINT_VAR(TxBufStatus);
	    if (TxBufStatus == STATUS_BUF_EMPT)
	    {
		    ret = I2C_TxDataEx(channel, len, pData);
			//TRACE_LEVEL(TRACE_IICTRANSFER | TRACE_INTEG_TEST, ("%s(%d, %d) = %d\n", _FUNC_, channel, len, ret));	
	    }
    }

	if(ret == ERR_SUCCESS)
	{
		return ERR_PENDING;
	}
	else
	{
	    return ERR_FAILED;
	}
}

static void IicTransfer_RxData(unsigned char ChanNum, unsigned char EventInd)
{
	int nRet = ERR_SUCCESS;
	uint8 len = 0;
	//uint8 i = 0;
	Ipmb* pIpmb = &g_Mmc.m_Ipmb;
	IicTransfer* pTransfer = (IicTransfer*)pIpmb->m_pTransfer;
	IicCmd cmd={0};
    uint8 RxBufStatus;
    uint8 TxBufStatus;
    uint8 EventStatus;

	Assert(pIpmb);
	
	if(pTransfer->m_bErrorCount > 4)
	{
		pTransfer->m_bErrorCount = 0;
	}
	
	if(EVENT_RXOK_MASK & EventInd)
	{
		do
		{
	        nRet = I2C_GetStatus(ChanNum, &RxBufStatus, &TxBufStatus, &EventStatus);
	        if(nRet == ERR_SUCCESS && RxBufStatus != STATUS_BUF_EMPT)
	        {
				len = I2C_RxData(ChanNum, MAX_IPMICMD_LEN, &cmd);

				TRACE_LEVEL(TRACE_IICTRANSFER | TRACE_INTEG_TEST, ("%s() Dump Data: ", _FUNC_));	
				DUMP_BYTE_LEVEL(TRACE_IICTRANSFER | TRACE_INTEG_TEST, (uint8*)&cmd, len);	

				if(len < MIN_IPMICMD_LEN)
				{
					return;
				}
	        }
			else
			{
				break;
			}
			
		}while(1);
		
	}
		
	//Trace("{%d}", EventInd);
	if(len > 0)
	{
		EventInd = EVENT_RX_SUCCESS;
	}
	else if(EVENT_TXOK_MASK & EventInd)
	{
		EventInd = EVENT_TX_SUCCESS;
	}
	else if(EVENT_TXNA_MASK & EventInd || EVENT_TXBY_MASK & EventInd || EVENT_TXBE_MASK & EventInd)
	{
		EventInd = EVENT_TX_FAILED;
	}
	else
	{
		EventInd = EVENT_RX_FAILED;
	}
	
	Ipmb_driverCallBack(pIpmb, (TransferEvent)EventInd, (uint8*) &cmd, len);
	
}

void IicTransfer_Init(IicTransfer* pTransfer, Ipmb* pIpmb, uint8 localIpmbAddress, uint8 channel, uint8 rxBuffNum)
{
	int ret = 0;
	TRACE_LEVEL(TRACE_MAIN, ("%s(), channel=%d\n", _FUNC_, channel));
	
	memset(pTransfer, 0, sizeof(IicTransfer));
	Transfer_Init((Transfer*)pTransfer, pIpmb);
	
	pTransfer->m_bChannel = channel;
    pTransfer->m_bEventMask = EVENT_TXOK_MASK
		| EVENT_TXNA_MASK
		| EVENT_TXBY_MASK
		| EVENT_TXBE_MASK
		| EVENT_RXOK_MASK 
		| EVENT_RXNA_MASK
		| EVENT_RXBY_MASK
		| EVENT_RXBE_MASK
		;
	
	((Transfer*)pTransfer)->TxData = (TransferFun)IicTransfer_TxData;

    ret = I2C_Config(channel, rxBuffNum, 0);
	ret = I2C_RegClient(channel
		, pTransfer->m_bEventMask
		, (void *)IicTransfer_RxData
		, 1
		, &localIpmbAddress	
		);
	Assert(ret == ERR_SUCCESS);

}

int UartTransfer_TxData(UartTransfer* pTransfer, uint8* pData, uint8 len)
{
	Ipmb* pIpmb = &g_Mmc.m_UartIpmb;
	int nRet = ERR_SUCCESS;
	
	nRet = Uart_TxData(pTransfer->m_uartId, pData, len);

	if(ERR_SUCCESS == nRet)
	{
		Ipmb_driverCallBack(pIpmb, EVENT_TX_SUCCESS, Null, 0);
	}

	return nRet;
}

void UartTransfer_RxDataCallBack(unsigned char uartId, unsigned char* pData, unsigned char len)
{
	Ipmb* pIpmb = &g_Mmc.m_UartIpmb;
	
	Assert(pIpmb);
	
	Ipmb_driverCallBack(pIpmb, EVENT_RX_SUCCESS, pData, len);
}

void UartTransfer_Init(UartTransfer* pTransfer, Ipmb* pIpmb, uint8 uartId)
{
	Transfer_Init((Transfer*)pTransfer, pIpmb);
	
	pTransfer->m_uartId = uartId;
	((Transfer*)pTransfer)->TxData = (TransferFun)UartTransfer_TxData;

	UART_Init(uartId);
	
}

